#include "seetafacetools.h"


SeetafaceTools::SeetafaceTools() :
    fdp(new seeta::FaceDetector(SettingModel(
                                    "face_detector.csta").GetModel())),
    flp(new seeta::FaceLandmarker(SettingModel(
                                      "face_landmarker_pts5.csta").GetModel())),
    frp(new seeta::FaceRecognizer(SettingModel(
                                      "face_recognizer.csta").GetModel()))
{

}

bool SeetafaceTools::isFace(const SeetaImageData &img)
{
    check = fdp->detect(img);
    return check.size != 0;
}

SeetaFaceInfoArray SeetafaceTools::getFaceInfoArray(const SeetaImageData &img)
{
    if(!isFace(img))
    {
        qDebug() << "Not Found Face!\n";
    }
    return check;
}

std::vector<SeetaPointF> SeetafaceTools::getMarkPoint(const SeetaImageData &img)
{
    if(!isFace(img))
    {
        qDebug() << "Not Found Face!\n";
        return std::vector<SeetaPointF>();
    }
    return flp->mark(img, getBiggestFaceRect(img));
}

std::shared_ptr<float> SeetafaceTools::getFaceFeatures(const SeetaImageData &img)
{
    if(!isFace(img))
    {
        qDebug() << "Not Found Face!\n";
        return nullptr;
    }
    std::shared_ptr<float> FaceFeatures(new float[frp->GetExtractFeatureSize()]);
    if(frp->Extract(img, getMarkPoint(img).data(), FaceFeatures.get())) // !
    {

    }
    else
    {
        qDebug() << "Get FaceFeatures failed!\n";
    }
    return FaceFeatures;
}

float SeetafaceTools::compareFace(const float *f1, const float *f2) const
{
    return frp->CalculateSimilarity(f1,f2);
}

bool SeetafaceTools::isTheSamePerson(const float *f1, const float *f2) const
{
    return compareFace(f1,f2) >= 0.60;
}

SeetaFaceInfo SeetafaceTools::getBiggestFaceInfo(const SeetaImageData& img)
{
    if(!isFace(img))
    {
        qDebug() << "Not found face!\n";
        return SeetaFaceInfo();
    }
    std::vector<SeetaFaceInfo> faces(check.data, check.data + check.size);
    std::partial_sort (faces.begin(), faces.begin() + 1, faces.end(), [] (SeetaFaceInfo a, SeetaFaceInfo b) {
            return a.pos.width > b.pos.width;
        });
    return faces[0];
}

SeetaRect SeetafaceTools::getBiggestFaceRect(const SeetaImageData& img)
{
    return getBiggestFaceInfo(img).pos;
}

